<script setup lang="ts">
import { uploadAvatar } from '@/api/user';
import { UploaderFileListItem, UploaderBeforeRead } from 'vant';
import { onMounted, ref, Ref, watch } from 'vue';
import { showToast, showLoadingToast, closeToast } from 'vant';

const avatar = defineModel() as Ref<string>;
const fileList = ref([
  { url: '' }
]);

onMounted(() => {
  fileList.value[0].url = avatar.value;
});

watch(() => avatar.value, (newVal) => {
  if (newVal && newVal !== fileList.value[0].url) {
    fileList.value[0].url = newVal;
  }
});

// 修复类型问题，适配UploaderBeforeRead类型
const beforeRead: UploaderBeforeRead = (file) => {
  // 处理可能是数组的情况
  if (Array.isArray(file)) {
    return file.every(f => checkFile(f));
  }
  return checkFile(file);
};

// 抽取检查文件的逻辑为单独函数
function checkFile(file: File): boolean {
  const isImage = file.type.indexOf('image') !== -1;
  
  if (!isImage) {
    showToast('请上传图片格式文件!');
    return false;
  }
  
  const isLt2M = file.size / 1024 / 1024 < 2;
  
  if (!isLt2M) {
    showToast('上传图片大小不能超过 2MB!');
    return false;
  }
  
  return true;
}

const upload = async (upload: UploaderFileListItem | UploaderFileListItem[]) => {
  if (!Array.isArray(upload)) {
    const avatarItem = upload as UploaderFileListItem;
    if (avatarItem.file) {
      try {
        showLoadingToast({
          message: '正在上传...',
          forbidClick: true,
          duration: 0
        });
        
        await uploadAvatar(avatarItem.file);
        avatar.value = avatarItem.content as string;
        
        closeToast();
        showToast({
          type: 'success',
          message: '头像上传成功'
        });
      } catch (error) {
        closeToast();
        showToast({
          type: 'fail',
          message: '头像上传失败'
        });
        console.error('头像上传失败', error);
      }
    }
  }
};
</script>

<template>
    <div class="avatar-uploader">
        <van-uploader
            v-model="fileList"
            :max-count="1"
            :before-read="beforeRead"
            :after-read="upload"
            :preview-size="120"
            :preview-image="true"
            :preview-full-image="true"
            class="uploader"
        >
            <template #preview-cover>
                <div class="preview-cover">
                    <div class="upload-hint">
                        <van-icon name="photograph" />
                        <span>更换头像</span>
                    </div>
                </div>
            </template>
        </van-uploader>
        
        <div class="avatar-tips">
            点击头像可以上传新头像<br>
            支持 JPG、PNG 格式，大小不超过 2MB
        </div>
    </div>
</template>

<style lang="scss" scoped>
.avatar-uploader {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    
    .uploader {
        position: relative;
        cursor: pointer;
        
        .van-uploader__preview {
            border-radius: 50%;
            overflow: hidden;
            border: 3px solid #fff;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            
            &:hover .preview-cover {
                opacity: 1;
            }
        }
        
        .preview-cover {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            background: rgba(0, 0, 0, 0.5);
            opacity: 0;
            transition: opacity 0.3s;
            border-radius: 50%;
            
            .upload-hint {
                color: white;
                display: flex;
                flex-direction: column;
                align-items: center;
                
                .van-icon {
                    font-size: 24px;
                    margin-bottom: 4px;
                }
                
                span {
                    font-size: 12px;
                }
            }
        }
    }
    
    .avatar-tips {
        text-align: center;
        color: #999;
        font-size: 12px;
        line-height: 1.5;
    }
}
</style>